import { _decorator, Component, Node, Vec3, Collider2D, Contact2DType, IPhysics2DContact } from 'cc';
import { ObjectPool } from '../Core/ObjectPool';

const { ccclass, property } = _decorator;

// Bullet configuration interface
export interface BulletConfig {
    direction: Vec3;
    speed: number;
    damage: number;
    lifetime: number;
    owner: Node;
    poolKey: string;
    piercing?: boolean;
}

@ccclass('Bullet')
export class Bullet extends Component {
    private _direction: Vec3 = new Vec3();
    private _speed: number = 500;
    private _damage: number = 10;
    private _lifetime: number = 2;
    private _timer: number = 0;
    private _owner: Node = null;
    private _poolKey: string = "";
    private _piercing: boolean = false;
    private _hitEnemies: Set<string> = new Set();
    
    /**
     * Initialize the bullet with the provided configuration
     */
    public initialize(config: BulletConfig): void {
        this._direction.set(config.direction);
        this._speed = config.speed;
        this._damage = config.damage;
        this._lifetime = config.lifetime;
        this._owner = config.owner;
        this._poolKey = config.poolKey;
        this._timer = 0;
        this._piercing = config.piercing || false;
        this._hitEnemies.clear();
        
        // Activate collider
        this.enableCollider();
    }
    
    start() {
        this.enableCollider();
    }
    
    update(deltaTime: number) {
        // Update lifetime timer
        this._timer += deltaTime;
        if (this._timer >= this._lifetime) {
            this.recycleBullet();
            return;
        }
        
        // Move the bullet
        const movement = new Vec3(
            this._direction.x * this._speed * deltaTime,
            this._direction.y * this._speed * deltaTime,
            0
        );
        
        this.node.position = this.node.position.add(movement);
    }
    
    private enableCollider(): void {
        const collider = this.getComponent(Collider2D);
        if (collider) {
            collider.on(Contact2DType.BEGIN_CONTACT, this.onCollisionEnter, this);
        }
    }
    
    private onCollisionEnter(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact): void {
        // Check if collision is with an enemy
        const enemy = otherCollider.node;
        const enemyId = enemy.uuid;
        
        // Skip if already hit this enemy (for piercing bullets)
        if (this._hitEnemies.has(enemyId)) {
            return;
        }
        
        // Apply damage to enemy if it has a health component
        const enemyHealth = enemy.getComponent('EnemyController');
        if (enemyHealth) {
            enemyHealth.takeDamage(this._damage);
            this._hitEnemies.add(enemyId);
            
            // If not piercing, recycle the bullet
            if (!this._piercing) {
                this.recycleBullet();
            }
        }
    }
    
    private recycleBullet(): void {
        // Return to object pool
        if (this._poolKey) {
            ObjectPool.instance.returnObject(this._poolKey, this.node);
        } else {
            this.node.destroy();
        }
    }
    
    // Clean up event listeners when bullet is destroyed
    onDestroy() {
        const collider = this.getComponent(Collider2D);
        if (collider) {
            collider.off(Contact2DType.BEGIN_CONTACT, this.onCollisionEnter, this);
        }
    }
} 